package com.yx.cloud.animator;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import com.yx.cloud.R;
import java.util.ArrayList;

public class AreaClickView extends View implements View.OnTouchListener {
    // 设置需要用到的变量
    public static final float RADIUS = 20f;// 圆的半径 = 20
    public static final float CLICK_RADIUS = 40f;// 点击效果圆的半径 = 40
    public static final int VIEW_TYPE_YINGXING = 1;
    public static final int VIEW_TYPE_INXNI = 2;
    private Point currentPoint;// 当前点坐标
    private Paint mPaint;// 绘图画笔
    private Paint mClickPaint;//点击效果画笔
    private Paint mAreaPaint;//框框画笔
    private ArrayList<Point> points;
    public ImageView ivAdd;
    public CheckBox cbTimes;
    public CheckBox cbStartClean;

    private int currentAlpha = -1;
    private boolean flag = false;

    private RestrictRect area;

    protected int areaStrokeColor = 0;
    protected int areaFillColor = 0;

    protected Bitmap areaDelete;
    protected Bitmap areaRotate;
    protected Bitmap areaDrag;

    public boolean endAnimator = false;
    public int viewType = VIEW_TYPE_YINGXING;

    // 构造方法(初始化画笔)
    public AreaClickView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    private void initView() {
        // 初始化画笔
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(getResources().getColor(R.color.click_circle_color));
        mClickPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mClickPaint.setColor(getResources().getColor(R.color.click_circle_color));
        mAreaPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mAreaPaint.setColor(areaStrokeColor);

        area = new RestrictRect();

        areaDelete = BitmapFactory.decodeResource(this.getResources(), R.mipmap.area_delete_help);
        areaRotate = BitmapFactory.decodeResource(this.getResources(), R.mipmap.area_rotate_help);
        areaDrag = BitmapFactory.decodeResource(this.getResources(), R.mipmap.area_drag_help);

        areaStrokeColor = getResources().getColor(R.color.area_stroke);
        areaFillColor = getResources().getColor(R.color.area_fill);
    }

    // 复写onDraw()从而实现绘制逻辑
    // 绘制逻辑:先在初始点画圆,通过监听当前坐标值(currentPoint)的变化,每次变化都调用onDraw()重新绘制圆,从而实现圆的平移动画效果
    @Override
    protected void onDraw(Canvas canvas) {
        if(ivAdd.getX() != 0f && !flag) {
            flag = true;
            points = initPoints();
            startAnimation(points.get(5),points.get(0),500,500);
        }else {
            if(!flag){
                invalidate();
            }
        }
        // 如果当前点坐标为空(即第一次)
        if (currentPoint == null) {
            currentPoint = new Point(0, 0);
        } else {
            if(area.center != null){
                if(area.move){
                    area.center = currentPoint;
                    area.left = area.center.getX() - 150;
                    area.top =  area.center.getY() - 100;
                    area.right = area.center.getX() + 150;
                    area.bottom = area.center.getY() + 100;
                }
                if(area.drag){
                    area.right = currentPoint.getX();
                    area.bottom = currentPoint.getY();
                }

                if(area.center.getX() == points.get(3).getX() && area.center.getY() == points.get(3).getY()){
                    area.left = area.center.getX() - 150;
                    area.top =  area.center.getY() - 100;
                    area.right = area.center.getX() + 150;
                    area.bottom = area.center.getY() + 100;
                }

                mAreaPaint.setColor(areaFillColor);
                mAreaPaint.setStyle(Paint.Style.FILL);
                //矩形填充
                canvas.drawRect(area.left, area.top, area.right, area.bottom, mAreaPaint);

                mAreaPaint.setColor(areaStrokeColor);
                mAreaPaint.setStyle(Paint.Style.STROKE);
                //区域时虚线填充
                mAreaPaint.setPathEffect(new DashPathEffect(new float[]{10, 8}, 0));
                mAreaPaint.setStrokeWidth(3.0f);
                //矩形边框
                canvas.drawRect(area.left, area.top, area.right, area.bottom, mAreaPaint);

                if(!area.save){
                    //矩形点的图标
                    canvas.drawBitmap(areaDelete, area.left - areaDelete.getWidth() / 2, area.top - areaDelete.getHeight() / 2, null);
                    //canvas.drawBitmap(areaRotate, area.right - areaRotate.getWidth() / 2 , area.top - areaRotate.getHeight() / 2 , null);
                    canvas.drawBitmap(areaDrag, area.right - areaDrag.getWidth() / 2, area.bottom - areaDrag.getHeight() / 2, null);
                }
            }

            if(viewType == VIEW_TYPE_YINGXING){
                mPaint.setColor(getResources().getColor(R.color.click_circle_color));
                mClickPaint.setColor(getResources().getColor(R.color.click_circle_color));
            }else {
                mPaint.setColor(getResources().getColor(R.color.button_color2));
                mClickPaint.setColor(getResources().getColor(R.color.button_color2));
            }

            float x = currentPoint.getX();
            float y = currentPoint.getY();
            if(x != 0 && y != 0){
                mPaint.setAlpha(204);
                canvas.drawCircle(x, y, RADIUS, mPaint);
                if(currentAlpha != -1){
                    mClickPaint.setAlpha(currentAlpha);
                    canvas.drawCircle(x, y, CLICK_RADIUS, mClickPaint);
                }
            }
        }
    }

    private ArrayList<Point> initPoints(){
        int[] location = new int[2];
        ArrayList<Point> points = new ArrayList<>();

        ivAdd.getLocationInWindow(location);
        com.yx.cloud.animator.Point addPoint = new com.yx.cloud.animator.Point(location[0] + ivAdd.getWidth() / 2f,location[1] + ivAdd.getHeight() / 2f);
        points.add(addPoint);

        cbTimes.getLocationInWindow(location);
        com.yx.cloud.animator.Point areaPoint = new com.yx.cloud.animator.Point(location[0] + cbTimes.getWidth() / 2f,location[1] + cbTimes.getHeight() / 2f);
        points.add(areaPoint);

        cbStartClean.getLocationInWindow(location);
        com.yx.cloud.animator.Point linePoint = new com.yx.cloud.animator.Point(location[0] + cbStartClean.getWidth() / 2f,location[1] + cbStartClean.getHeight() / 2f);
        points.add(linePoint);

        com.yx.cloud.animator.Point point3 = new com.yx.cloud.animator.Point(location[0] + 200,location[1] - 250);
        points.add(point3);//区域初始位置中心点
        com.yx.cloud.animator.Point point4 = new com.yx.cloud.animator.Point(point3.getX() - 200,point3.getY() - 300);
        points.add(point4);//区域移动后位置中心点

        com.yx.cloud.animator.Point point5 = new com.yx.cloud.animator.Point(addPoint.getX() + 150,addPoint.getY() - 80);
        //com.yx.b34.animator.Point point5 = new com.yx.b34.animator.Point(100,1500);
        points.add(point5);//初始位置

        return points;
    }

    void startAnimation(Point start,Point end,int duration,int startDelay){

        // 步骤2:创建动画对象 & 设置初始值 和 结束值
        ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), start,end);
        // 参数说明
        // 参数1：TypeEvaluator 类型参数 - 使用自定义的PointEvaluator(实现了TypeEvaluator接口)
        // 参数2：初始动画的对象点
        // 参数3：结束动画的对象点

        // 步骤3：设置动画参数
        anim.setDuration(duration);
        anim.setRepeatCount(0);
        anim.setStartDelay(startDelay);
        // 设置动画时长

        // 步骤3：通过 值 的更新监听器，将改变的对象手动赋值给当前对象
        // 此处是将 改变后的坐标值对象 赋给 当前的坐标值对象
        // 设置 值的更新监听器
        // 即每当坐标值（Point对象）更新一次,该方法就会被调用一次
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                currentPoint = (Point) animation.getAnimatedValue();
                // 将每次变化后的坐标值（估值器PointEvaluator中evaluate（）返回的Piont对象值）到当前坐标值对象（currentPoint）
                // 从而更新当前坐标值（currentPoint）
                if(currentPoint.getX() == points.get(4).getX() && currentPoint.getY() == points.get(4).getY()){
                    currentAlpha = -1;
                    Point point6 = new Point(currentPoint.getX() + 150,currentPoint.getY() + 100);
                    if(points.get(points.size() - 1).getX() != point6.getX() || points.get(points.size() - 1).getY() != point6.getY()){
                        points.add(point6);//区域移动后右下角坐标
                        Log.d("animator","add point6");
                    }
                }
                if(points.size() >= 7 && currentPoint.getX() == points.get(6).getX() && currentPoint.getY() == points.get(6).getY()){
                    Point point7 = new Point(currentPoint.getX() + 80,currentPoint.getY() + 80);
                    if(points.get(points.size() - 1).getX() != point7.getX() || points.get(points.size() - 1).getY() != point7.getY()){
                        points.add(point7);////区域放大后右下角坐标
                        Log.d("animator","add point7");
                    }
                }

                // 步骤4：每次赋值后就重新绘制，从而实现动画效果
                invalidate();
                // 调用invalidate()后,就会刷新View,即才能看到重新绘制的界面,即onDraw()会被重新调用一次
                // 所以坐标值每改变一次,就会调用onDraw()一次
            }
        });

        anim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                if(currentPoint != null){
                    if(currentPoint.getX() == points.get(3).getX() && currentPoint.getY() == points.get(3).getY()){
                        currentAlpha = 127;
                    }
                    if(currentPoint.getX() == points.get(0).getX() && currentPoint.getY() == points.get(0).getY()){
                        mClickPaint.setColor(getResources().getColor(R.color.click_circle_color));
                    }
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if(endAnimator){
                    return;
                }
                if(currentPoint.getX() == points.get(0).getX() && currentPoint.getY() == points.get(0).getY()){
                    startAlphaAnimation(200);
                    startAnimation(points.get(0),points.get(3),500,200);
                } else if(currentPoint.getX() == points.get(3).getX() && currentPoint.getY() == points.get(3).getY()){
                    startAlphaAnimation(200);
                    area.move = true;
                    startAnimation(points.get(3),points.get(4),800,200);
                } else if(currentPoint.getX() == points.get(4).getX() && currentPoint.getY() == points.get(4).getY()){
                    currentAlpha = -1;
                    area.move = false;
                    startAnimation(points.get(4),points.get(6),500,0);
                }else if(currentPoint.getX() == points.get(6).getX() && currentPoint.getY() == points.get(6).getY()){
                    startAlphaAnimation(200);
                    area.move = false;
                    area.drag = true;
                    Log.d("animator","add point6 to point7");
                    startAnimation(points.get(6),points.get(7),500,0);
                }else if(currentPoint.getX() == points.get(7).getX() && currentPoint.getY() == points.get(7).getY()){
                    area.move = false;
                    area.drag = false;
                    currentAlpha = -1;
                    Log.d("animator","add point7 to point1");
                    startAnimation(points.get(7),points.get(1),500,0);
                } else if(currentPoint.getX() == points.get(1).getX() && currentPoint.getY() == points.get(1).getY()){
                    startAlphaAnimation(200);
                    cbTimes.setChecked(true);
                    startAnimation(points.get(1),points.get(2),500,200);
                }else if(currentPoint.getX() == points.get(2).getX() && currentPoint.getY() == points.get(2).getY()){
                    startAlphaAnimation(200);
                    area.save = true;
                    //cbStartClean.setChecked(true);
                    area.clear();
                    cbTimes.setChecked(false);
                    cbStartClean.setChecked(false);
                    startAnimation(points.get(5),points.get(0),500,866);
                    //Point endPoint = new Point((points.get(1).getX()),(points.get(1).getY() + 200));
                    //startAnimation(points.get(2),points.get(2),666,200);
                }/*else if(currentPoint.getX() == points.get(1).getX() && currentPoint.getY() == points.get(1).getY() + 200){
                    area.clear();
                    cbTimes.setChecked(false);
                    cbStartClean.setChecked(false);
                    startAnimation(points.get(5),points.get(0),500,1000);
                }*/
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

        // 启动动画
        anim.start();
    }

    void startAlphaAnimation(int duration){

        // 步骤2:创建动画对象 & 设置初始值 和 结束值
        ValueAnimator anim = ValueAnimator.ofInt(0,127);
        // 参数说明
        // 参数1：TypeEvaluator 类型参数 - 使用自定义的PointEvaluator(实现了TypeEvaluator接口)
        // 参数2：初始动画的对象点
        // 参数3：结束动画的对象点

        // 步骤3：设置动画参数
        anim.setDuration(duration);
        anim.setRepeatCount(0);
        // 设置动画时长

        // 步骤3：通过 值 的更新监听器，将改变的对象手动赋值给当前对象
        // 此处是将 改变后的坐标值对象 赋给 当前的坐标值对象
        // 设置 值的更新监听器
        // 即每当坐标值（Point对象）更新一次,该方法就会被调用一次
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                currentAlpha = (int) animation.getAnimatedValue();
                // 将每次变化后的坐标值（估值器PointEvaluator中evaluate（）返回的Piont对象值）到当前坐标值对象（currentPoint）
                // 从而更新当前坐标值（currentPoint）

                // 步骤4：每次赋值后就重新绘制，从而实现动画效果
                invalidate();
                // 调用invalidate()后,就会刷新View,即才能看到重新绘制的界面,即onDraw()会被重新调用一次
                // 所以坐标值每改变一次,就会调用onDraw()一次
            }
        });

        anim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                currentAlpha = -1;
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if(currentPoint.getX() == points.get(0).getX() && currentPoint.getY() == points.get(0).getY()){
                    currentAlpha = -1;
                    area.center = points.get(3);
                }
                if(currentPoint.getX() == points.get(1).getX() && currentPoint.getY() == points.get(1).getY()){
                    currentAlpha = -1;
                    mClickPaint.setColor(getResources().getColor(R.color.click_circle_end_color));
                }
                if(currentPoint.getX() == points.get(2).getX() && currentPoint.getY() == points.get(2).getY()){
                    currentAlpha = -1;
                    mClickPaint.setColor(getResources().getColor(R.color.click_circle_color));
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

        // 启动动画
        anim.start();
    }

    public ArrayList<Point> getPoints() {
        return points;
    }

    public void setPoints(ArrayList<Point> points) {
        this.points = points;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return false;
    }
}
